package com.smileus.dal;

/**   
 * @Title: BaseHibernateDAO.java
 * @Description:本DAO层实现了通用的数据操�
 * @author dongheng  
 * @date May 18, 2009 10:37:08 AM
 * @version V1.0   
 * @hestory
 *    
 */

import java.io.Serializable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.classic.QueryTranslatorImpl;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;

import com.ibatis.common.util.Page;
import com.smileus.common.Env;
import com.smileus.util.ReflectionUtil;
import com.smileus.util.StringUtil;


/**
 * DAO操作基类<br>
 * 本DAO层实现了通用的数据操作
 * 
 * @author 董恒
 * 
 * @param <E>
 *            POJO实体对象
 * @param <ID>
 *            ID
 */
@SuppressWarnings("unchecked")
public class BaseHibernateDAO extends HibernateDaoSupport {

	private static final Map<Class, Map<String, Field>> fieldsMap = new HashMap<Class, Map<String, Field>>();

	public BaseHibernateDAO(SessionFactory sessionFactory) {
		setHibernateTemplate(new HibernateTemplate(sessionFactory));
	}

	public BaseHibernateDAO(String sessionFactoryId) {
		SessionFactory sessionFactory = (SessionFactory) Env.getBean(sessionFactoryId);
		setHibernateTemplate(new HibernateTemplate(sessionFactory));
	}

	protected Map<String, Object> creatCondition(Class clazz, Map<String, ?> param) {
		StringBuilder buf = new StringBuilder("from ").append(clazz.getSimpleName()).append(" where 1=1 ");
		return creatCondition(buf.toString(), param);
	}

	protected Map<String, Object> creatCondition(String hql, Map<String, ?> param) {
		Assert.notNull(hql, "传入 dynamicFind方法的hql不能为空!");
		int size = param.size();
		String[] paramNames = new String[size];
		Object[] values = new Object[size];
		Map<String, Object> result = new HashMap<String, Object>();

		StringBuilder strbuf = new StringBuilder(200);

		if (hql.toLowerCase().indexOf("where") == -1) {
			strbuf.append(hql).append(" where 1=1 ");
		}

		int num = 0;
		for (Entry<String, ?> entry : param.entrySet()) {
			String key = entry.getKey();
			if (entry.getValue() != null) {//注意：值不为null的 才座位条件
				strbuf.append(" and ").append(key).append("=:").append(key);
				paramNames[num] = key;
				values[num] = entry.getValue();
			}
		}

		result.put("hql", strbuf.toString());
		result.put("paramNames", paramNames);
		result.put("values", values);

		return result;
	}

	/**
	 * 注意：作为动态参数的条件，请不要写预先写在hql字符串中 适用于下列基本形式： 1. from Person 或者 2. from Person
	 * where name = '张三'
	 * 
	 * @param <E>
	 * @param hql
	 * @param param
	 * @return
	 */
	public <E extends Serializable> List<E> dynamicQuery(Class<E> clazz, Map<String, ?> param) {
		Map<String, Object> map = creatCondition(clazz, param);
		String hql = (String) map.get("hql");
		String[] paramNames = (String[]) map.get("paramNames");
		Object[] values = (Object[]) map.get("values");
		return getHibernateTemplate().findByNamedParam(hql, paramNames, values);
	}

	/**
	 * 以valueBean形式查找，注意valueBean中的属性名和参数名一致 from Person p where p.name =:name
	 * 
	 * @param <T>
	 * @param hql
	 * @param valueBean
	 * @return
	 */
	public <T extends Serializable> List<T> queryByValueBean(Class<T> clazz, final String hql, final Object valueBean) {
		return queryByValueBean(hql, valueBean);
	}

	/**
	 * 以valueBean形式查找，注意valueBean中的属性名和参数名一致 from Person p where p.name =:name
	 * 
	 * @param <T>
	 * @param hql
	 * @param valueBean
	 * @return
	 */
	public <T> List<T> queryByValueBean(final String hql, final Object valueBean) {
		final Map<String, Field> fields = getFields(valueBean);
		final Map<String, Object> prepareMap = StringUtil.processValueBeanHQL(hql, fields, valueBean);
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = createVaulueBeanQuery(session, prepareMap, fields, valueBean, true);
				return query.list();
			}
		});
	}

	/**
	 * 注意：作为动态参数的条件，请不要写预先写在hql字符串中 适用于下列基本形式： 1. from Person 或者 2. from Person
	 * where name = '张三'
	 * 
	 * @param <T>
	 * @param sql
	 * @param param
	 * @return
	 */
	public <T extends Serializable> List<T> queryByMap(final String sql, final Map<String, Object> param) {
		final Map<String, Object> prepareMap = StringUtil.processMapHQL(sql, param);
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = createMapQuery(session, prepareMap, param, false);
				return query.list();
			}
		});
	}

	/**
	 * 以valueBean形式查找，注意valueBean中的属性名和参数名一致 from Person p where p.name =:name
	 * 
	 * @param <T>
	 * @param sql
	 * @param valueBean
	 * @return
	 */
	public <T> List<T> queryBySQLValueBean(final String sql, final Class<T> clazz, final Object valueBean) {
		final Map<String, Field> fields = getFields(valueBean);
		final Map<String, Object> prepareMap = StringUtil.processValueBeanHQL(sql, fields, valueBean);
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				SQLQuery query = (SQLQuery) createVaulueBeanQuery(session, prepareMap, fields, valueBean, false);
				query.addEntity(clazz);
				return query.list();
			}
		});
	}

	/**
	 * 注意：作为动态参数的条件，请不要写预先写在hql字符串中 适用于下列基本形式： 1. from Person 或者 2. from Person
	 * where name = '张三'
	 * 
	 * @param <T>
	 * @param sql
	 * @param param
	 * @return
	 */
	public <T extends Serializable> List<T> queryBySQLMap(final String sql, final Class<T> clazz, final Map<String, Object> param) {
		final Map<String, Object> prepareMap = StringUtil.processMapHQL(sql, param);
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				SQLQuery query = (SQLQuery) createMapQuery(session, prepareMap, param, false);
				query.addEntity(clazz);
				return query.list();
			}
		});
	}

	/**
	 * 批量保存
	 * 
	 * @param list
	 */
	public void btachSave(final List list) {
		getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				for (int i = 0; i < list.size(); i++) {
					session.save(list.get(i));
				}
				return null;
			}
		});
	}

	/**
	 * 批量更新
	 * 
	 * @param list
	 */
	public void btachUpdate(final List list) {
		getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				for (int i = 0; i < list.size(); i++) {
					session.update(list.get(i));
				}
				return null;
			}
		});

		// Session session =
		// getHibernateTemplate().getSessionFactory().getCurrentSession();
		// Transaction tx = session.beginTransaction();
		// for (int i = 0; i < list.size(); i++) {
		// session.update(list.get(i));
		// if (i % 100 == 0) {
		// // 100条批量一次提交
		// session.flush();
		// session.clear();
		// }
		// }
		// tx.commit();
		// session.close();
	}

	/**
	 * 批量删除
	 * 
	 * @param list
	 */
	public void btachRemove(final List list) {
		getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				for (int i = 0; i < list.size(); i++) {
					session.delete(list.get(i));
				}
				return null;
			}
		});
	}

	/**
	 * 保存实体
	 * 
	 * @param <E>
	 * @param entity
	 */
	public <E extends Serializable> void save(E entity) {
		getHibernateTemplate().save(entity);
	}
	/**
	 * 保存或更新实体
	 * 
	 * @param <E>
	 * @param entity
	 */
	public <E extends Serializable> void saveOrUpdate(E entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	/**
	 * 删除实体
	 * 
	 * @param <E>
	 * @param entity
	 */
	public <E extends Serializable> void remove(E entity) {
		getHibernateTemplate().delete(entity);
	}

	/**
	 * 查找所有实体
	 * 
	 * @param <E>
	 * @param entityClass
	 * @return
	 */
	public <E extends Serializable> List<E> queryAll(Class<E> entityClass) {
		return getHibernateTemplate().find("from " + entityClass.getSimpleName());
	}

	/**
	 * 更新实体
	 * 
	 * @param <E>
	 * @param entity
	 */
	public <E> void update(E entity) {
		getHibernateTemplate().update(entity);
	}

	/**
	 * 注意：当记录不存在时候，get方法返回null
	 * 
	 * @param <T>
	 * @param entityClass
	 * @param id
	 * @return
	 */
	public <E> E get(Class<E> entityClass, Serializable id) {
		return (E) getHibernateTemplate().get(entityClass, id);
	}

	/**
	 * 注意：当记录不存在时候，产生异常
	 * 
	 * @param <T>
	 * @param entityClass
	 * @param id
	 * @return
	 */
	public <E> E load(Class<E> entityClass, Serializable id) {
		return (E) getHibernateTemplate().load(entityClass, id);
	}

	/**
	 * 通过变参查找
	 * 
	 * @param <E>
	 * @param clazz
	 * @param hql
	 * @param param
	 * @return
	 */
	public List queryByParam(String hql, Object... param) {
		return getHibernateTemplate().find(hql, param);
	}

	/**
	 * 通过变参查找
	 * 
	 * @param <E>
	 * @param clazz
	 * @param hql
	 * @param param
	 * @return
	 */
	public <E> List<E> queryByParam(Class<E> clazz, String hql, Object... param) {
		return getHibernateTemplate().find(hql, param);
	}

	/**
	 * @param <E>
	 * @param clazz
	 * @param hql
	 * @param param
	 * @return
	 */
	public <E> Iterator<E> iterate(String hql, Object... param) {
		return getHibernateTemplate().iterate(hql, param);
	}

	/**
	 * @param <E>
	 * @param clazz
	 * @param hql
	 * @param param
	 * @return
	 */
	public <E> Iterator<E> iterate(Class<E> clazz, String hql, Object... param) {
		return getHibernateTemplate().iterate(hql, param);
	}

	/**
	 * 通过参数查找唯一性实体
	 * 
	 * @param <E>
	 * @param entityClass
	 * @param hql
	 * @param param
	 * @return
	 */
	public <E extends Serializable> E queryUniqueEntity(Class<E> entityClass, final String hql, final Object... param) {
		return (E) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException, SQLException {
				Query query = createQuery(s, hql, param);
				return query.uniqueResult();
			}
		});
	}

	/**
	 * 通过参数查找唯一性实体
	 * 
	 * @param <E>
	 * @param entityClass
	 * @param hql
	 * @param param
	 * @return
	 */
	public Object queryUniqueEntity(final String hql, final Object... param) {
		return getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException, SQLException {
				Query query = createQuery(s, hql, param);
				return query.uniqueResult();
			}
		});
	}

	/**
	 * 查找指定HQL并返回INT型
	 * 
	 * @param hql
	 *            HQL语句
	 * @param param
	 *            可变参数列表
	 * @return INT
	 */
	public int queryInteger(final String hql, final Object... param) {
		return (Integer) queryUniqueEntity(hql, param);
	}

	public BigInteger queryBigInteger(final String hql, final Object... param) {
		return (BigInteger) queryUniqueEntity(hql, param);
	}

	/**
	 * 查找指定HQL并返回Long型
	 * 
	 * @param hql
	 *            HQL语句
	 * @param param
	 *            可变参数列表
	 * @return INT
	 */
	public Long queryLong(final String hql, final Object... param) {
		return (Long) queryUniqueEntity(hql, param);
	}

	/**
	 * 获取hql语句中返回的记录条数，通过转成SQL来进行查询，解决hql不能在distinct，group by结果集上使用count的问题
	 */

	public BigDecimal queryBigDecimal(final String hql, final Object... param) {
		return (BigDecimal) queryUniqueEntity(hql, param);
	}

	/**
	 * 查找指定属性的实体集合
	 * 
	 * @param entityClass
	 *            实体
	 * @param propertyName
	 *            属性名
	 * @param value
	 *            条件
	 * @return 实体集合
	 */
	public <E> List<E> queryByProperty(Class<E> entityClass, String propertyName, Object value) {
		String queryStr = "from " + entityClass.getName() + " as model where model." + propertyName + "=?";
		return getHibernateTemplate().find(queryStr, value);
	}

	public <E> E merge(E entity) {
		return (E) getHibernateTemplate().merge(entity);
	}

	/**
	 * 清除实体的锁定状态<br>
	 * 方法未测
	 * 
	 * @param entity
	 *            实体
	 */
	public void attachClean(Object entity) {
		getHibernateTemplate().lock(entity, LockMode.NONE);
	}

	public Query createQuery(Session session, String hql, Object... objects) {
		Query query = session.createQuery(hql);
		if (objects != null) {
			for (int i = 0; i < objects.length; i++) {
				query.setParameter(i, objects[i]);
			}
		}
		return query;
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            页面对象
	 * @param hql
	 *            HQL语句
	 * @param valueBean
	 *            可变参数列表
	 * @return 分页数据
	 */
	public <T> Page<T> findPageByMap(final Page<T> page, final String hql, final Map<String, Object> param) {
		final Map<String, Object> prepareMap = StringUtil.processMapHQL(hql, param);
		return (Page<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = createMapQuery(session, prepareMap, param, true);
				return setHQLPageInfo(query, page, prepareMap);
			}
		});
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            页面对象
	 * @param hql
	 *            HQL语句
	 * @param valueBean
	 *            可变参数列表
	 * @return 分页数据
	 */
	public <T> Page<T> findPageByValueBean(final Page<T> page, final String hql, final Object valueBean) {
		if (logger.isDebugEnabled()) {
			logger.debug("开始查找指定HQL分页数据," + hql);
		}
		final Map<String, Field> fields = getFields(valueBean);
		final Map<String, Object> prepareMap = StringUtil.processValueBeanHQL(hql, fields, valueBean);
		return (Page<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = createVaulueBeanQuery(session, prepareMap, fields, valueBean, true);
				return setHQLPageInfo(query, page, prepareMap);
			}
		});
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            页面对象
	 * @param sql
	 *            HQL语句
	 * @param param
	 *            可变参数列表
	 * @return 分页数据
	 */
	public <T> Page<T> findPageBySQLMap(final Page<T> page, final Class<T> clazz, final String sql, final Map<String, Object> param) {
		final Map<String, Object> prepareMap = StringUtil.processMapHQL(sql, param);
		return (Page<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) {
				SQLQuery query = (SQLQuery) createMapQuery(session, prepareMap, param, false);
				query.addEntity(clazz);

				putCountSQL(prepareMap);
				SQLQuery queryCount = (SQLQuery) createMapQuery(session, prepareMap, param, false);
				page.setTotalCount(getCountByQuery(queryCount));

				return setSQLPageInfo(query, page);
			}
		});
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            页面对象
	 * @param sql
	 *            HQL语句
	 * @param param
	 *            可变参数列表
	 * @return 分页数据
	 */
	public <T> Page<T> findPageBySQLValueBean(final Page<T> page, final Class<T> clazz, final String sql, final Object valueBean) {
		final Map<String, Field> fields = getFields(valueBean);
		final Map<String, Object> prepareMap = StringUtil.processValueBeanHQL(sql, fields, valueBean);
		return (Page<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) {
				SQLQuery query = (SQLQuery) createVaulueBeanQuery(session, prepareMap, fields, valueBean, false);
				query.addEntity(clazz);

				putCountSQL(prepareMap);
				SQLQuery queryCount = (SQLQuery) createVaulueBeanQuery(session, prepareMap, fields, valueBean, false);
				page.setTotalCount(getCountByQuery(queryCount));

				return setSQLPageInfo(query, page);
			}
		});
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            页面对象
	 * @param hql
	 *            HQL语句
	 * @param param
	 *            可变参数列表
	 * @return 分页数据
	 */
	public <T> Page<T> findPageByArray(final Page<T> page, final String hql, final Object... param) {
		if (logger.isDebugEnabled()) {
			logger.debug("开始查找指定HQL分页数据," + hql);
		}
		return (Page<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException, SQLException {
				Query query = createQuery(s, hql, param);
				page.setTotalCount(getHQLCount(hql, param));
				query.setFirstResult(page.getFirst());
				query.setMaxResults(page.getPageSize());
				page.setResult(query.list());
				if (logger.isDebugEnabled()) {
					logger.debug("查找指定HQL分页数据成功," + hql);
				}
				return page;
			}
		});
	}

	public Long getHQLCount(String hql, final Object... param) {
		QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(hql, hql, Collections.EMPTY_MAP, (SessionFactoryImplementor) this.getSessionFactory());
		queryTranslator.compile(Collections.EMPTY_MAP, true);
		final String countSQL = optimizeCountSQL(queryTranslator.getSQLString());
		return (Long) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createSQLQuery(countSQL);
				int size = param.length;
				for (int i = 0; i < size; i++) {
					query.setParameter(i, param[i]);
				}
				return getCountByQuery(query);
			}
		});
	}

	public Long getHQLCount(String hql, Map<String, Object> prepareMap) {
		final List<Object> paramList = (List<Object>) prepareMap.get("paramList");
		QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(hql, hql, Collections.EMPTY_MAP, (SessionFactoryImplementor) this.getSessionFactory());
		queryTranslator.compile(Collections.EMPTY_MAP, true);
		final String countSQL = optimizeCountSQL(queryTranslator.getSQLString());
		return (Long) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createSQLQuery(countSQL);
				int size = paramList.size();
				for (int i = 0; i < size; i++) {
					query.setParameter(i, paramList.get(i));
				}
				return getCountByQuery(query);
			}
		});
	}

	protected static Map<String, Field> getFields(Object valueBean) {
		Assert.notNull(valueBean);
		Class clazz = valueBean.getClass();
		Map<String, Field> fields = fieldsMap.get(clazz);
		if (fields == null) {
			fields = ReflectionUtil.getDeclaredFieldMap(valueBean);
			fieldsMap.put(clazz, fields);
		}
		return fields;
	}

	public <T> List<T> queryByMapFromCache(final String hql, final Map<String, Object> param) {
		final Map<String, Object> prepareMap = StringUtil.processMapHQL(hql, param);
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) {
				Query query = createMapQuery(session, prepareMap, param, true);
				query.setCacheable(true);
				return query.list();
			}
		});
	}

	public <T> List<T> queryByValueBeanFromCache(final String hql, final Map<String, Object> param, final Object valueBean) {

		final Map<String, Field> fields = getFields(valueBean);
		final Map<String, Object> prepareMap = StringUtil.processValueBeanHQL(hql, fields, valueBean);
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) {
				Query query = createVaulueBeanQuery(session, prepareMap, fields, valueBean, true);
				query.setCacheable(true);
				return query.list();
			}
		});
	}

	/**
	 * 通过参数从缓存中查找唯一性实体
	 * 
	 * @param <E>
	 * @param entityClass
	 * @param hql
	 * @param param
	 * @return
	 */
	public <T> List<T> queryByArrayFromCache(final String hql, final Object... param) {
		return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException, SQLException {
				Query query = createQuery(s, hql, param);
				query.setCacheable(true);
				return query.list();
			}
		});
	}

	/**
	 * 通过参数从缓存中查找唯一性实体
	 * 
	 * @param <E>
	 * @param entityClass
	 * @param hql
	 * @param param
	 * @return
	 */
	public <T> T getEntityFromCache(final String hql, final Object... param) {
		return (T) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException, SQLException {
				Query query = createQuery(s, hql, param);
				query.setCacheable(true);
				return query.uniqueResult();
			}
		});
	}

	/*
	 * ***************************************************************************
	 * private methods
	 * *************************************************************************
	 */
	private Query createMapQuery(Session session, Map<String, Object> prepareMap, Map<String, Object> param, boolean isHQLQuery) {
		String hql = (String) prepareMap.get("hql");
		Set<String> keySet = (Set<String>) prepareMap.get("keySet");
		Query query = createRelevantQuery(session, hql, isHQLQuery);
		Object value = null;
		String key = null;
		for (Entry<String, Object> entry : param.entrySet()) {
			value = entry.getValue();
			key = entry.getKey();
			// 当且仅当value不为null，且keySet中有此参数时，才添加参数
			if (value != null && keySet.contains(key) && StringUtil.NULL_CONTENT.equals(value) == false) {
				query.setParameter(key, value);
			}
		}

		return query;
	}

	private Query createVaulueBeanQuery(Session session, Map<String, Object> prepareMap, Map<String, Field> fields, Object valueBean, boolean isHQLQuery) {
		String hql = (String) prepareMap.get("hql");
		Set<String> keySet = (Set<String>) prepareMap.get("keySet");
		Query query = createRelevantQuery(session, hql, isHQLQuery);
		Object value = null;
		String key = null;
		try {
			for (Entry<String, Field> entry : fields.entrySet()) {
				value = entry.getValue().get(valueBean);
				key = entry.getKey();
				// 当且仅当value不为null，且keySet中有此参数时，才添加参数
				if (value != null && keySet.contains(key) && StringUtil.NULL_CONTENT.equals(value) == false) {
					query.setParameter(key, value);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		return query;
	}

	private Query createRelevantQuery(Session session, String queryString, boolean isHQLQuery) {
		if (isHQLQuery) {
			return session.createQuery(queryString);
		} else {
			return session.createSQLQuery(queryString);
		}
	}

	/**
	 * 查找指定HQL并返回Long型
	 * 
	 * @param sql
	 *            HQL语句
	 * @param param
	 *            可变参数列表
	 * @return INT
	 */
	private String optimizeCountSQL(String sql) {
		String lowerCase = sql.toLowerCase();
		int fromIndex = lowerCase.indexOf("from");
		int groupbyIndex = lowerCase.indexOf("group by");
		int orderbyIndex = lowerCase.indexOf("order by");

		if (groupbyIndex == -1) {
			if (orderbyIndex == -1) {
				sql = "select count(1) " + sql.substring(fromIndex);
			} else {
				sql = "select count(1) " + sql.substring(fromIndex, orderbyIndex);
			}
		} else {
			if (orderbyIndex == -1) {
				sql = "select count(1) from (select 1 " + sql.substring(fromIndex) + ")";
			} else {
				sql = "select count(1) from (select 1 " + sql.substring(fromIndex, orderbyIndex) + ")";
			}
		}

		return sql;
	}

	private <T> Page<T> setHQLPageInfo(Query query, Page page, Map<String, Object> prepareMap) {
		Long totalCount = 0L;
		totalCount = getHQLCount(query.getQueryString(), prepareMap);
		page.setTotalCount(totalCount);
		query.setFirstResult(page.getFirst());
		query.setMaxResults(page.getPageSize());
		page.setResult(query.list());
		return page;
	}

	private <T> Page<T> setSQLPageInfo(Query query, Page page) {
		query.setFirstResult(page.getFirst());
		query.setMaxResults(page.getPageSize());
		page.setResult(query.list());
		return page;
	}

	// put total count sql
	private void putCountSQL(Map<String, Object> prepareMap) {
		String sql = (String) prepareMap.get("hql");
		String countSQL = optimizeCountSQL(sql);
		prepareMap.put("hql", countSQL);
	}

	private long getCountByQuery(Query query) {
		Object obj = query.list().get(0);
		long result = 0;
		if (obj instanceof Number) {
			result = ((Number) obj).longValue();
		} else {
			throw new RuntimeException("取记录条数返回值类型异常！" + obj.getClass().getName());
		}
		return result;
	}
}
